/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include <gtest/gtest.h>

#include <algorithm>
#include <array>
#include <cstdint>
#include <cstring>
#include <functional>
#include <string>
#include <vector>

#include <mc/common.h>
#include <mc/dict.h>
#include "../../../libraries/mctp/mctp.h"
#include "../../../libraries/ncsi/ncsi_mellanox.h"
#include "../../../libraries/ncsi/ncsi_protocol.h"
#include "../../../libraries/ncsi_over_mctp/ncsi_over_mctp_mellanox.h"
#include "../../../libraries/ncsi_over_mctp/ncsi_over_mctp_standard.h"

namespace mc {
class dict;
}

namespace dev {
mc::dict get_ncsi_command_ctx(uint8_t package_id, uint8_t channel_id, uint8_t packet_type,
                              uint8_t expect_rsp_packet_type);
mc::dict get_oem_command_ctx(uint8_t package_id, uint8_t channel_id);
uint32_t convert_speed_mbps(uint32_t speed_mbps);
bool convert_full_duplex(uint8_t full_duplex);
uint8_t convert_link_status(uint8_t link_status);
std::string get_link_width_str(uint8_t link_width);
std::string get_link_speed_str(uint8_t link_speed);
std::string get_medium_type_str(uint8_t medium_type);
std::string get_connector_type_str(uint8_t connector_type);
std::string get_identifier_str(uint8_t identifier);
float covert_micro_to_milli(uint16_t value);
void set_mctp_request_handler(std::function<bool(const mc::dict&, const std::vector<uint8_t>&,
                                                 std::string&)> handler);

// Functions from ncsi_over_mctp_mellanox.cpp
bool check_response_data(oem_mlnx_common_rsp_t* rsp, uint8_t command_id, uint8_t parameter);
mc::dict get_oem_command_ctx_mellanox(uint8_t channel_id, uint8_t package_id);
} // namespace dev

namespace {

// 定义测试中使用的常量
#define RESP_CODE_FAILED     0x0001
#define REASON_CODE_FAILED   0x0001

constexpr uint16_t host_to_be16(uint16_t value) {
    return static_cast<uint16_t>(((value & 0x00FFU) << 8U) | ((value & 0xFF00U) >> 8U));
}

class ncsi_over_mctp_mellanox_test : public ::testing::Test {
protected:
    ncsi_over_mctp_mellanox_test()
        : m_mctp(nullptr, 0, dev::MCTP_MESSAGE_TYPE_NCSI, ""), m_ncsi(m_mctp) {
    }

    void TearDown() override {
        dev::set_mctp_request_handler(nullptr);
    }

    template <typename T>
    static std::string to_binary_string(const T& value) {
        return std::string(reinterpret_cast<const char*>(&value), sizeof(T));
    }

    template <typename T>
    static std::string to_sized_string(const T& value, size_t length) {
        return std::string(reinterpret_cast<const char*>(&value), length);
    }

    dev::mctp                     m_mctp;
    dev::ncsi_over_mctp_mellanox  m_ncsi;
};

// 测试check_response_data函数
TEST(ncsi_over_mctp_mellanox_utils, check_response_data_returns_true_for_successful_response) {
    oem_mlnx_common_rsp_t rsp;
    rsp.response_code = host_to_be16(RESP_CODE_SUCCESS);
    rsp.reason_code = host_to_be16(REASON_CODE_SUCCESS);
    rsp.manufacturer_id = MELLANOX_MANUFACTURE_ID_REP;
    rsp.command_id = OEM_MLNX_GET_TEMP_CMD;
    rsp.parameter = OEM_MLNX_GET_TEMP_PARA;

    EXPECT_TRUE(dev::check_response_data(&rsp, OEM_MLNX_GET_TEMP_CMD, OEM_MLNX_GET_TEMP_PARA));
}

TEST(ncsi_over_mctp_mellanox_utils, check_response_data_returns_false_for_failed_response_code) {
    oem_mlnx_common_rsp_t rsp = {};
    rsp.response_code = host_to_be16(RESP_CODE_FAILED);
    rsp.reason_code = host_to_be16(RESP_CODE_FAILED); // Both must fail for the function to return false
    rsp.manufacturer_id = MELLANOX_MANUFACTURE_ID_REP;
    rsp.command_id = OEM_MLNX_GET_TEMP_CMD;
    rsp.parameter = OEM_MLNX_GET_TEMP_PARA;

    EXPECT_FALSE(dev::check_response_data(&rsp, OEM_MLNX_GET_TEMP_CMD, OEM_MLNX_GET_TEMP_PARA));
}

TEST(ncsi_over_mctp_mellanox_utils, check_response_data_returns_false_for_failed_reason_code) {
    oem_mlnx_common_rsp_t rsp = {};
    rsp.response_code = host_to_be16(RESP_CODE_FAILED);
    rsp.reason_code = host_to_be16(RESP_CODE_FAILED); // Both must fail for the function to return false
    rsp.manufacturer_id = MELLANOX_MANUFACTURE_ID_REP;
    rsp.command_id = OEM_MLNX_GET_TEMP_CMD;
    rsp.parameter = OEM_MLNX_GET_TEMP_PARA;

    EXPECT_FALSE(dev::check_response_data(&rsp, OEM_MLNX_GET_TEMP_CMD, OEM_MLNX_GET_TEMP_PARA));
}

TEST(ncsi_over_mctp_mellanox_utils, check_response_data_returns_false_for_wrong_manufacturer_id) {
    oem_mlnx_common_rsp_t rsp;
    rsp.response_code = host_to_be16(RESP_CODE_SUCCESS);
    rsp.reason_code = host_to_be16(REASON_CODE_SUCCESS);
    rsp.manufacturer_id = 0x12345678; // 错误的制造商ID
    rsp.command_id = OEM_MLNX_GET_TEMP_CMD;
    rsp.parameter = OEM_MLNX_GET_TEMP_PARA;

    EXPECT_FALSE(dev::check_response_data(&rsp, OEM_MLNX_GET_TEMP_CMD, OEM_MLNX_GET_TEMP_PARA));
}

TEST(ncsi_over_mctp_mellanox_utils, check_response_data_returns_false_for_wrong_command_id) {
    oem_mlnx_common_rsp_t rsp;
    rsp.response_code = host_to_be16(RESP_CODE_SUCCESS);
    rsp.reason_code = host_to_be16(REASON_CODE_SUCCESS);
    rsp.manufacturer_id = MELLANOX_MANUFACTURE_ID_REP;
    rsp.command_id = 0xFF; // 错误的命令ID
    rsp.parameter = OEM_MLNX_GET_TEMP_PARA;

    EXPECT_FALSE(dev::check_response_data(&rsp, OEM_MLNX_GET_TEMP_CMD, OEM_MLNX_GET_TEMP_PARA));
}

TEST(ncsi_over_mctp_mellanox_utils, check_response_data_returns_false_for_wrong_parameter) {
    oem_mlnx_common_rsp_t rsp;
    rsp.response_code = host_to_be16(RESP_CODE_SUCCESS);
    rsp.reason_code = host_to_be16(REASON_CODE_SUCCESS);
    rsp.manufacturer_id = MELLANOX_MANUFACTURE_ID_REP;
    rsp.command_id = OEM_MLNX_GET_TEMP_CMD;
    rsp.parameter = 0xFF; // 错误的参数

    EXPECT_FALSE(dev::check_response_data(&rsp, OEM_MLNX_GET_TEMP_CMD, OEM_MLNX_GET_TEMP_PARA));
}

// 测试get_oem_command_ctx_mellanox函数
TEST(ncsi_over_mctp_mellanox_utils, get_oem_command_ctx_mellanox_sets_expected_fields) {
    auto ctx = dev::get_oem_command_ctx_mellanox(0x01, 0x02);
    ASSERT_FALSE(ctx.empty());
    EXPECT_EQ(ctx.at("PacketType").as<int64_t>(), OEM_COMMAND);
    EXPECT_EQ(ctx.at("ExpectRspPacketType").as<int64_t>(), OEM_COMMAND_RSP);
    EXPECT_EQ(ctx.at("ChannelId").as<int64_t>(), 0x01);
    EXPECT_EQ(ctx.at("PackageId").as<int64_t>(), 0x02);
}

// 测试get_temp_info函数
TEST_F(ncsi_over_mctp_mellanox_test, get_temp_info_returns_false_for_null_pointer) {
    dev::ncsi_temp_info_t temp_info;
    bool result = m_ncsi.get_temp_info(0, 0, 0, nullptr);
    EXPECT_FALSE(result);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_temp_info_returns_false_when_request_fails) {
    dev::ncsi_temp_info_t temp_info;
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            return false; // 请求失败
        });

    bool result = m_ncsi.get_temp_info(0, 0, 0, &temp_info);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_temp_info_returns_false_for_empty_response) {
    dev::ncsi_temp_info_t temp_info;
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            rsp = ""; // 空响应
            return true;
        });

    bool result = m_ncsi.get_temp_info(0, 0, 0, &temp_info);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_temp_info_returns_false_for_short_response) {
    dev::ncsi_temp_info_t temp_info;
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            rsp = std::string(OEM_MLNX_TEMP_RSP_MIN_LEN - 1, '\0'); // 短响应
            return true;
        });

    bool result = m_ncsi.get_temp_info(0, 0, 0, &temp_info);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_temp_info_returns_false_for_invalid_response_data) {
    dev::ncsi_temp_info_t temp_info;
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            oem_mlnx_temp_rsp_t response = {};
            // 设置无效的制造商ID
            response.public_rsp_header.manufacturer_id = 0x12345678;
            rsp = to_binary_string(response);
            return true;
        });

    bool result = m_ncsi.get_temp_info(0, 0, 0, &temp_info);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_temp_info_returns_true_for_valid_response) {
    dev::ncsi_temp_info_t temp_info;
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            oem_mlnx_temp_rsp_t response = {};
            response.public_rsp_header.response_code = host_to_be16(RESP_CODE_SUCCESS);
            response.public_rsp_header.reason_code = host_to_be16(REASON_CODE_SUCCESS);
            response.public_rsp_header.manufacturer_id = MELLANOX_MANUFACTURE_ID_REP;
            response.public_rsp_header.command_id = OEM_MLNX_GET_TEMP_CMD;
            response.public_rsp_header.parameter = OEM_MLNX_GET_TEMP_PARA;
            response.max_operating_temp = 80;
            response.cur_temp = 60;
            rsp = to_binary_string(response);
            return true;
        });

    bool result = m_ncsi.get_temp_info(0, 0, 0, &temp_info);
    EXPECT_TRUE(result);
    EXPECT_TRUE(handler_called);
    EXPECT_EQ(temp_info.max_operating_temp, 80);
    EXPECT_EQ(temp_info.cur_temp, 60);
}

// 测试get_mac_addr函数
TEST_F(ncsi_over_mctp_mellanox_test, get_mac_addr_returns_false_for_null_pointer) {
    uint8_t mac_addr[6];
    bool result = m_ncsi.get_mac_addr(0, 0, nullptr, 6);
    EXPECT_FALSE(result);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_mac_addr_returns_false_when_request_fails) {
    uint8_t mac_addr[6];
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            return false; // 请求失败
        });

    bool result = m_ncsi.get_mac_addr(0, 0, mac_addr, 6);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_mac_addr_returns_false_for_empty_response) {
    uint8_t mac_addr[6];
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            rsp = ""; // 空响应
            return true;
        });

    bool result = m_ncsi.get_mac_addr(0, 0, mac_addr, 6);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_mac_addr_returns_false_for_wrong_response_length) {
    uint8_t mac_addr[6];
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            rsp = std::string(OEM_MLNX_MAC_ADDR_RSP_LEN - 1, '\0'); // 错误长度
            return true;
        });

    bool result = m_ncsi.get_mac_addr(0, 0, mac_addr, 6);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_mac_addr_returns_false_for_invalid_response_data) {
    uint8_t mac_addr[6];
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            oem_mlnx_mac_addr_rsp_t response = {};
            // 设置无效的制造商ID
            response.public_rsp_header.manufacturer_id = 0x12345678;
            rsp = to_sized_string(response, OEM_MLNX_MAC_ADDR_RSP_LEN);
            return true;
        });

    bool result = m_ncsi.get_mac_addr(0, 0, mac_addr, 6);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_mac_addr_returns_true_for_valid_response) {
    uint8_t mac_addr[6];
    bool handler_called = false;
    uint8_t expected_mac[6] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            oem_mlnx_mac_addr_rsp_t response = {};
            response.public_rsp_header.response_code = host_to_be16(RESP_CODE_SUCCESS);
            response.public_rsp_header.reason_code = host_to_be16(REASON_CODE_SUCCESS);
            response.public_rsp_header.manufacturer_id = MELLANOX_MANUFACTURE_ID_REP;
            response.public_rsp_header.command_id = OEM_MLNX_GET_PF_MAC_CMD;
            response.public_rsp_header.parameter = OEM_MLNX_GET_PF_MAC_PARA;
            memcpy(response.mac_addr, expected_mac, 6);
            rsp = to_sized_string(response, OEM_MLNX_MAC_ADDR_RSP_LEN);
            return true;
        });

    bool result = m_ncsi.get_mac_addr(0, 0, mac_addr, 6);
    EXPECT_TRUE(result);
    EXPECT_TRUE(handler_called);
    EXPECT_EQ(memcmp(mac_addr, expected_mac, 6), 0);
}

// 测试get_default_mac_addr函数
TEST_F(ncsi_over_mctp_mellanox_test, get_default_mac_addr_returns_false_for_null_pointer) {
    uint8_t mac_addr[6];
    bool result = m_ncsi.get_default_mac_addr(0, 0, nullptr, 6);
    EXPECT_FALSE(result);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_default_mac_addr_returns_false_when_request_fails) {
    uint8_t mac_addr[6];
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            return false; // 请求失败
        });

    bool result = m_ncsi.get_default_mac_addr(0, 0, mac_addr, 6);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_default_mac_addr_returns_false_for_empty_response) {
    uint8_t mac_addr[6];
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            rsp = ""; // 空响应
            return true;
        });

    bool result = m_ncsi.get_default_mac_addr(0, 0, mac_addr, 6);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_default_mac_addr_returns_false_for_wrong_response_length) {
    uint8_t mac_addr[6];
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            rsp = std::string(OEM_MLNX_PORT_ID_RSP_LEN - 1, '\0'); // 错误长度
            return true;
        });

    bool result = m_ncsi.get_default_mac_addr(0, 0, mac_addr, 6);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_default_mac_addr_returns_false_for_invalid_response_data) {
    uint8_t mac_addr[6];
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            oem_mlnx_port_id_rsp_t response;
            // response is zero-initialized
            // 设置无效的制造商ID
            response.public_rsp_header.manufacturer_id = 0x12345678;
            rsp = to_sized_string(response, OEM_MLNX_PORT_ID_RSP_LEN);
            return true;
        });

    bool result = m_ncsi.get_default_mac_addr(0, 0, mac_addr, 6);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_default_mac_addr_returns_true_for_valid_response) {
    uint8_t mac_addr[6];
    bool handler_called = false;
    uint8_t expected_mac[6] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            oem_mlnx_port_id_rsp_t response;
            // response is zero-initialized
            response.public_rsp_header.response_code = host_to_be16(RESP_CODE_SUCCESS);
            response.public_rsp_header.reason_code = host_to_be16(REASON_CODE_SUCCESS);
            response.public_rsp_header.manufacturer_id = MELLANOX_MANUFACTURE_ID_REP;
            response.public_rsp_header.command_id = OEM_MLNX_GET_PORT_ID_CMD;
            response.public_rsp_header.parameter = OEM_MLNX_GET_PORT_ID_PARA;
            memcpy(response.mac_addr, expected_mac, 6);
            rsp = to_sized_string(response, OEM_MLNX_PORT_ID_RSP_LEN);
            return true;
        });

    bool result = m_ncsi.get_default_mac_addr(0, 0, mac_addr, 6);
    EXPECT_TRUE(result);
    EXPECT_TRUE(handler_called);
    EXPECT_EQ(memcmp(mac_addr, expected_mac, 6), 0);
}

// 测试reset_nic函数
TEST_F(ncsi_over_mctp_mellanox_test, reset_nic_returns_false_when_request_fails) {
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            return false; // 请求失败
        });

    bool result = m_ncsi.reset_nic(0, 0);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, reset_nic_returns_false_for_empty_response) {
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            rsp = ""; // 空响应
            return true;
        });

    bool result = m_ncsi.reset_nic(0, 0);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, reset_nic_returns_false_for_wrong_response_length) {
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            rsp = std::string(OEM_MLNX_RESET_NIC_LEN - 1, '\0'); // 错误长度
            return true;
        });

    bool result = m_ncsi.reset_nic(0, 0);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, reset_nic_returns_false_for_invalid_response_data) {
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            oem_mlnx_reset_nic_rsp_t response;
            // response is zero-initialized
            // 设置无效的制造商ID
            response.public_rsp_header.manufacturer_id = 0x12345678;
            rsp = to_sized_string(response, OEM_MLNX_RESET_NIC_LEN);
            return true;
        });

    bool result = m_ncsi.reset_nic(0, 0);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, reset_nic_returns_true_for_valid_response) {
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            oem_mlnx_reset_nic_rsp_t response;
            // response is zero-initialized
            response.public_rsp_header.response_code = host_to_be16(RESP_CODE_SUCCESS);
            response.public_rsp_header.reason_code = host_to_be16(REASON_CODE_SUCCESS);
            response.public_rsp_header.manufacturer_id = MELLANOX_MANUFACTURE_ID_REP;
            response.public_rsp_header.command_id = OEM_MLNX_RESET_NCI_CMD;
            response.public_rsp_header.parameter = OEM_MLNX_RESET_NIC_PARA;
            rsp = to_sized_string(response, OEM_MLNX_RESET_NIC_LEN);
            return true;
        });

    bool result = m_ncsi.reset_nic(0, 0);
    EXPECT_TRUE(result);
    EXPECT_TRUE(handler_called);
}

// 测试get_lldp_capability函数
TEST_F(ncsi_over_mctp_mellanox_test, get_lldp_capability_returns_false_for_null_pointer) {
    uint8_t lldp_capability;
    bool result = m_ncsi.get_lldp_capability(0, 0, nullptr);
    EXPECT_FALSE(result);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_lldp_capability_returns_false_when_request_fails) {
    uint8_t lldp_capability;
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            return false; // 请求失败
        });

    bool result = m_ncsi.get_lldp_capability(0, 0, &lldp_capability);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_lldp_capability_returns_false_for_empty_response) {
    uint8_t lldp_capability;
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            rsp = ""; // 空响应
            return true;
        });

    bool result = m_ncsi.get_lldp_capability(0, 0, &lldp_capability);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_lldp_capability_returns_false_for_wrong_response_length) {
    uint8_t lldp_capability;
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            rsp = std::string(OEM_MLNX_LLDP_RSP_LEN - 1, '\0'); // 错误长度
            return true;
        });

    bool result = m_ncsi.get_lldp_capability(0, 0, &lldp_capability);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_lldp_capability_returns_false_for_invalid_response_data) {
    uint8_t lldp_capability;
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            oem_mlnx_lldp_rsp_t response;
            // response is zero-initialized
            // 设置无效的制造商ID
            response.public_rsp_header.manufacturer_id = 0x12345678;
            rsp = to_sized_string(response, OEM_MLNX_LLDP_RSP_LEN);
            return true;
        });

    bool result = m_ncsi.get_lldp_capability(0, 0, &lldp_capability);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_lldp_capability_returns_true_for_valid_response_lldp_enabled) {
    uint8_t lldp_capability;
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            oem_mlnx_lldp_rsp_t response;
            // response is zero-initialized
            response.public_rsp_header.response_code = host_to_be16(RESP_CODE_SUCCESS);
            response.public_rsp_header.reason_code = host_to_be16(REASON_CODE_SUCCESS);
            response.public_rsp_header.manufacturer_id = MELLANOX_MANUFACTURE_ID_REP;
            response.public_rsp_header.command_id = OEM_MLNX_GET_LLDP_CMD;
            response.public_rsp_header.parameter = OEM_MLNX_GET_LLDP_PARA;
            response.lldp_tx_mode = 1; // LLDP使能
            rsp = to_sized_string(response, OEM_MLNX_LLDP_RSP_LEN);
            return true;
        });

    bool result = m_ncsi.get_lldp_capability(0, 0, &lldp_capability);
    EXPECT_TRUE(result);
    EXPECT_TRUE(handler_called);
    EXPECT_EQ(lldp_capability, 1);
}

TEST_F(ncsi_over_mctp_mellanox_test, get_lldp_capability_returns_true_for_valid_response_lldp_disabled) {
    uint8_t lldp_capability;
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            oem_mlnx_lldp_rsp_t response;
            // response is zero-initialized
            response.public_rsp_header.response_code = host_to_be16(RESP_CODE_SUCCESS);
            response.public_rsp_header.reason_code = host_to_be16(REASON_CODE_SUCCESS);
            response.public_rsp_header.manufacturer_id = MELLANOX_MANUFACTURE_ID_REP;
            response.public_rsp_header.command_id = OEM_MLNX_GET_LLDP_CMD;
            response.public_rsp_header.parameter = OEM_MLNX_GET_LLDP_PARA;
            response.lldp_tx_mode = 0; // LLDP禁用
            rsp = to_sized_string(response, OEM_MLNX_LLDP_RSP_LEN);
            return true;
        });

    bool result = m_ncsi.get_lldp_capability(0, 0, &lldp_capability);
    EXPECT_TRUE(result);
    EXPECT_TRUE(handler_called);
    EXPECT_EQ(lldp_capability, 0);
}

// 测试set_lldp_capability函数
TEST_F(ncsi_over_mctp_mellanox_test, set_lldp_capability_returns_false_when_request_fails) {
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            return false; // 请求失败
        });

    bool result = m_ncsi.set_lldp_capability(0, 0, ENABLE_LLDP);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, set_lldp_capability_returns_false_for_empty_response) {
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            rsp = ""; // 空响应
            return true;
        });

    bool result = m_ncsi.set_lldp_capability(0, 0, ENABLE_LLDP);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, set_lldp_capability_returns_false_for_wrong_response_length) {
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            rsp = std::string(OEM_MLNX_LLDP_RSP_LEN - 1, '\0'); // 错误长度
            return true;
        });

    bool result = m_ncsi.set_lldp_capability(0, 0, ENABLE_LLDP);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, set_lldp_capability_returns_false_for_invalid_response_data) {
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            oem_mlnx_lldp_rsp_t response;
            // response is zero-initialized
            // 设置无效的制造商ID
            response.public_rsp_header.manufacturer_id = 0x12345678;
            rsp = to_sized_string(response, OEM_MLNX_LLDP_RSP_LEN);
            return true;
        });

    bool result = m_ncsi.set_lldp_capability(0, 0, ENABLE_LLDP);
    EXPECT_FALSE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, set_lldp_capability_returns_true_for_valid_response_enable) {
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            // 验证发送的数据是否包含正确的LLDP设置
            EXPECT_GE(data.size(), MELLANOX_COMMON_DATA_SIZE + 4);
            uint8_t lldp_data = data[data.size() - 1];
            EXPECT_EQ(lldp_data & 0x10, 0x10); // ENABLE_LLDP时bit4应该为1

            oem_mlnx_lldp_rsp_t response;
            // response is zero-initialized
            response.public_rsp_header.response_code = host_to_be16(RESP_CODE_SUCCESS);
            response.public_rsp_header.reason_code = host_to_be16(REASON_CODE_SUCCESS);
            response.public_rsp_header.manufacturer_id = MELLANOX_MANUFACTURE_ID_REP;
            response.public_rsp_header.command_id = OEM_MLNX_SET_LLDP_CMD;
            response.public_rsp_header.parameter = OEM_MLNX_SET_LLDP_PARA;
            rsp = to_sized_string(response, OEM_MLNX_LLDP_RSP_LEN);
            return true;
        });

    bool result = m_ncsi.set_lldp_capability(0, 0, ENABLE_LLDP);
    EXPECT_TRUE(result);
    EXPECT_TRUE(handler_called);
}

TEST_F(ncsi_over_mctp_mellanox_test, set_lldp_capability_returns_true_for_valid_response_disable) {
    bool handler_called = false;

    dev::set_mctp_request_handler(
        [&](const mc::dict& ctx, const std::vector<uint8_t>& data, std::string& rsp) -> bool {
            handler_called = true;
            // 验证发送的数据是否包含正确的LLDP设置
            EXPECT_GE(data.size(), MELLANOX_COMMON_DATA_SIZE + 4);
            uint8_t lldp_data = data[data.size() - 1];
            EXPECT_EQ(lldp_data & 0x10, 0x00); // DISABLE_LLDP时bit4应该为0

            oem_mlnx_lldp_rsp_t response;
            // response is zero-initialized
            response.public_rsp_header.response_code = host_to_be16(RESP_CODE_SUCCESS);
            response.public_rsp_header.reason_code = host_to_be16(REASON_CODE_SUCCESS);
            response.public_rsp_header.manufacturer_id = MELLANOX_MANUFACTURE_ID_REP;
            response.public_rsp_header.command_id = OEM_MLNX_SET_LLDP_CMD;
            response.public_rsp_header.parameter = OEM_MLNX_SET_LLDP_PARA;
            rsp = to_sized_string(response, OEM_MLNX_LLDP_RSP_LEN);
            return true;
        });

    bool result = m_ncsi.set_lldp_capability(0, 0, DISABLE_LLDP);
    EXPECT_TRUE(result);
    EXPECT_TRUE(handler_called);
}

} // namespace
